﻿ #region Disclaimer/Info
 
 /////////////////////////////////////////////////////////////////////////////////////////////////
 //
 //   File:		TrackBackHandler.cs
 //   Website:		http://dexterblogengine.com/
 //   Authors:		http://dexterblogengine.com/About.ashx
 //   Rev:		1
 //   Created:		19/01/2011
 //   Last edit:		19/01/2011
 //   License:		GNU Library General Public License (LGPL)
 // 
 //   For updated news and information please visit http://dexterblogengine.com/
 //   Dexter is hosted to Codeplex at http://dexterblogengine.codeplex.com
 //   For any question contact info@dexterblogengine.com
 //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 #endregion

using System;
using System.Web;
using Dexter.Web.HttpHandlers;
using Dexter.Dependency;
using Dexter.Domain.Model;
using Dexter.Services;
using Dexter.Web.Utils;

namespace Dexter.Web.HttpHandlers {
	public class TrackBackHandler : HttpHandlerBase {
		readonly IConfigurationService configurationService;
		readonly IPostService postService;
		readonly ITrackBackService trackBackService;
		readonly IUrlBuilder urlBuilder;
		readonly IWebUtils webUtils;

		/// <summary>
		/// 	Initializes a new instance of the <see cref = "TrackBackHandler" /> class.
		/// </summary>
		public TrackBackHandler ( IPostService postService ) {
			urlBuilder = DexterContainer.Resolve <IUrlBuilder> ( );
			configurationService = DexterContainer.Resolve <IConfigurationService> ( );
			webUtils = DexterContainer.Resolve <IWebUtils> ( );
			trackBackService = DexterContainer.Resolve<ITrackBackService> ( );
			this.postService = postService;
		}

		/// <summary>
		/// 	Enables processing of HTTP Web requests by a custom HttpHandler that implements the <see cref = "T:System.Web.IHttpHandler" /> interface.
		/// </summary>
		/// <param name = "context">An <see cref = "T:System.Web.HttpContext" /> object that provides references to the intrinsic server objects (for example, Request, Response, Session, and Server) used to service HTTP requests.</param>
		public override void ProcessRequest ( HttpContextBase context ) {
			var configuration = configurationService.Configuration;

			if ( !configuration.Tracking.EnableTrackBackReceive ) {
				throw new HttpException ( 404 , "File not found" );
			}

			int postId = context.Request.Params[ "id" ].ToInt32 ( 0 );
			string title = context.Request.Form[ "title" ];
			string excerpt = context.Request.Form[ "excerpt" ];
			string blogName = context.Request.Form[ "blog_name" ];
			string url = string.Empty;

			if ( context.Request.Params[ "url" ] != null ) {
				url = context.Request.Params[ "url" ].Split ( ',' )[ 0 ];
			}

			if ( !string.IsNullOrEmpty ( title ) && postId > 0 && !string.IsNullOrEmpty ( blogName ) ) {
				var post = postService.GetByKey ( postId );

				var requesturl = new Uri ( url );

				bool firstPingBack = trackBackService.IsFirstTrackbackBack ( postId , requesturl );

				var itemURl = urlBuilder.Post.Detail ( post );

				bool isSpam = IsSpamRequest ( url , itemURl );

				var trackBack = TrackBack.CreateNewTrackback ( post , requesturl , title );
				trackBack.Excerpt = excerpt;
				trackBack.IsSpam = isSpam;

				trackBackService.AddTrackBack ( postId , requesturl , title );

				if ( firstPingBack && !isSpam ) {
					context.Response.Write ( "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><response><error>0</error></response>" );
					context.Response.End ( );
				}
				else if ( !firstPingBack ) {
					context.Response.Write ( "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><response><error>Trackback already registered</error></response>" );
					context.Response.End ( );
				}
				else {
					context.Response.Write ( "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><response><error>The source page does not link</error></response>" );
					context.Response.End ( );
				}
			}
		}

		bool IsSpamRequest ( string sourceUrl , string targetUrl ) {
			var responseHtml = webUtils.DownloadWebPage ( new Uri ( sourceUrl ) );

			if ( string.IsNullOrEmpty ( responseHtml ) ) {
				return false;
			}

			return !responseHtml.ToLowerInvariant ( ).Contains ( targetUrl.ToLowerInvariant ( ) );
		}
	}
}
